#ifndef SOULLANG_SOULC_ERRORS_HPP
#define SOULLANG_SOULC_ERRORS_HPP

#include <map>
#include <string>
#include <iostream>
#include <exception>

#include "strings.hpp"
#include "termcolor.hpp"

#define GET_HELP_STR "Type -h or --help for get help"

namespace soulc {
	typedef enum {
		COMPILER_NO_ARGS_ERR = 1,
		COMPILER_UNKNOWN_ARG_ERR,
		COMPILER_NO_REQUIRED_ARGS_ERR,
		COMPILER_NO_PHRASE_FOR_BOOL_ARG_ERR,
		COMPILER_NO_STR_FOR_STR_ARG_ERR,

		COMPILER_UNABLE_TO_OPEN_SOURCE_FILE_ERR,
		COMPILER_SOURCE_FILENAME_ALREADY_SET_ERR,
		COMPILER_SOURCES_ALREADY_READ_ERR
	} Error;

	typedef enum {
		LEXER_SYNTAX_ERR = 1
	} CompilerError;

	const std::map<Error, std::string> errorTexts = {
		{COMPILER_NO_ARGS_ERR, "No arguments specified"},
		{COMPILER_UNKNOWN_ARG_ERR, "Unknown argument specified"},
		{COMPILER_NO_REQUIRED_ARGS_ERR, "No required arguments specified"},
		{COMPILER_NO_PHRASE_FOR_BOOL_ARG_ERR, "No true/false phrase for bool argument"},
		{COMPILER_NO_STR_FOR_STR_ARG_ERR, "No string for string argument"},

		{COMPILER_UNABLE_TO_OPEN_SOURCE_FILE_ERR, "Unable to open source file"},
		{COMPILER_SOURCE_FILENAME_ALREADY_SET_ERR, "Source filename is already set"},
		{COMPILER_SOURCES_ALREADY_READ_ERR, "Sources already read"}
	};

	const std::map<CompilerError, std::string> compilerErrorTexts = {
		{LEXER_SYNTAX_ERR, "Syntax error"}
	};

	
	void raiseError(Error error, std::string additionalText);
	void raiseError(Error error);

	void raiseCompilerError(CompilerError error, uint64_t line, uint64_t symbol, std::string erroneousCode);
	void raiseCompilerError(CompilerError error, uint64_t line, uint64_t symbol, std::string erroneousCode, std::string additionalText);
}

#endif
